/**
 * 事件服务
 * 用于跨项目数据同步和事件处理
 */
const EventModel = require('../config/models_config').event_model;
const BaseDataService = require('./base_data_service');
const AppError = require('../../../../framework/core/app_error');

/**
 * 事件类型常量
 */
const EVENT_TYPE = {
  // 项目事件
  PROJECT_CREATE: 'project_create',     // 创建项目
  PROJECT_UPDATE: 'project_update',     // 更新项目
  PROJECT_STATUS_CHANGE: 'project_status_change', // 项目状态变更
  
  // 任务事件
  TASK_CREATE: 'task_create',           // 创建任务
  TASK_UPDATE: 'task_update',           // 更新任务
  TASK_STATUS_CHANGE: 'task_status_change',  // 任务状态变更
  
  // 流程事件
  FLOW_CREATE: 'flow_create',           // 创建流程
  FLOW_UPDATE: 'flow_update',           // 更新流程
  FLOW_STATUS_CHANGE: 'flow_status_change',  // 流程状态变更
  
  // 文档事件
  DOC_CREATE: 'doc_create',             // 创建文档
  DOC_UPDATE: 'doc_update'              // 更新文档
};

/**
 * 项目标识常量
 */
const PROJECT_ID = {
  OA: 'oa',
  PLM: 'plm',
  SYSTEM: 'system'
};

class EventService {
  constructor() {
    this.eventModel = new EventModel();
  }

  /**
   * 发布事件
   * @param {String} eventType 事件类型
   * @param {Object} eventData 事件数据
   * @param {String} sourceProject 事件来源项目
   * @param {Array} targetProjects 目标项目列表
   * @returns {Promise<String>} 事件ID
   */
  async publishEvent(eventType, eventData, sourceProject, targetProjects = []) {
    if (!eventType || !eventData || !sourceProject) {
      throw new AppError('事件参数不完整', 10101);
    }
    
    console.log(`[EventService] 发布事件: ${eventType}, 来源: ${sourceProject}`);
    
    // 创建事件
    const event = {
      type: eventType,
      data: eventData,
      sourceProject,
      targetProjects,
      maxRetries: 3
    };
    
    // 添加到事件队列
    const eventId = await this.eventModel.addEvent(event);
    
    console.log(`[EventService] 事件已创建, ID: ${eventId}`);
    
    return eventId;
  }
  
  /**
   * 处理待处理事件
   * @param {Number} limit 处理事件数量限制
   * @returns {Promise<Object>} 处理结果统计
   */
  async processPendingEvents(limit = 10) {
    console.log(`[EventService] 开始处理待处理事件，最大数量: ${limit}`);
    
    // 获取待处理事件
    const events = await this.eventModel.getPendingEvents({ limit });
    
    if (!events || events.length === 0) {
      console.log('[EventService] 没有待处理事件');
      return { success: 0, failed: 0, total: 0 };
    }
    
    console.log(`[EventService] 找到 ${events.length} 个待处理事件`);
    
    // 处理统计
    const stats = {
      success: 0,
      failed: 0,
      total: events.length
    };
    
    // 依次处理事件
    for (const event of events) {
      try {
        // 更新事件状态为处理中
        await this.eventModel.updateEventStatus(
          event._id, 
          this.eventModel.STATUS.PROCESSING
        );
        
        // 根据事件类型调用相应处理函数
        const result = await this._processEventByType(event);
        
        if (result.success) {
          // 处理成功
          await this.eventModel.updateEventStatus(
            event._id,
            this.eventModel.STATUS.DONE,
            result.data || {}
          );
          stats.success++;
        } else {
          // 处理失败
          await this.eventModel.incrementRetry(event._id);
          await this.eventModel.updateEventStatus(
            event._id,
            this.eventModel.STATUS.FAILED,
            { error: result.error || '处理失败' }
          );
          stats.failed++;
        }
      } catch (err) {
        console.error(`[EventService] 处理事件 ${event._id} 异常:`, err);
        
        // 增加重试次数
        await this.eventModel.incrementRetry(event._id);
        
        // 更新为失败状态
        await this.eventModel.updateEventStatus(
          event._id,
          this.eventModel.STATUS.FAILED,
          { error: err.message || '处理异常' }
        );
        
        stats.failed++;
      }
    }
    
    console.log(`[EventService] 事件处理完成, 成功: ${stats.success}, 失败: ${stats.failed}`);
    
    return stats;
  }
  
  /**
   * 根据事件类型处理事件
   * @param {Object} event 事件对象
   * @returns {Promise<Object>} 处理结果
   */
  async _processEventByType(event) {
    if (!event || !event.type) {
      return { success: false, error: '无效事件' };
    }
    
    console.log(`[EventService] 处理事件类型: ${event.type}`);
    
    // 根据不同事件类型调用对应处理函数
    switch (event.type) {
      case EVENT_TYPE.PROJECT_CREATE:
      case EVENT_TYPE.PROJECT_UPDATE:
      case EVENT_TYPE.PROJECT_STATUS_CHANGE:
        return await this._processProjectEvent(event);
        
      case EVENT_TYPE.TASK_CREATE:
      case EVENT_TYPE.TASK_UPDATE:
      case EVENT_TYPE.TASK_STATUS_CHANGE:
        return await this._processTaskEvent(event);
        
      case EVENT_TYPE.FLOW_CREATE:
      case EVENT_TYPE.FLOW_UPDATE:
      case EVENT_TYPE.FLOW_STATUS_CHANGE:
        return await this._processFlowEvent(event);
        
      case EVENT_TYPE.DOC_CREATE:
      case EVENT_TYPE.DOC_UPDATE:
        return await this._processDocEvent(event);
        
      default:
        console.warn(`[EventService] 未知事件类型: ${event.type}`);
        return { success: false, error: '未知事件类型' };
    }
  }
  
  /**
   * 处理项目相关事件
   * @param {Object} event 事件对象
   * @returns {Promise<Object>} 处理结果
   */
  async _processProjectEvent(event) {
    console.log(`[EventService] 处理项目事件: ${event.type}`);
    
    // 调用目标项目的跨项目服务
    try {
      const results = {};
      
      // 针对每个目标项目处理
      for (const targetProject of event.targetProjects) {
        // 获取目标项目服务
        const targetService = global.CROSS_SERVICE 
          && global.CROSS_SERVICE[targetProject.toUpperCase()];
        
        if (!targetService) {
          results[targetProject] = { 
            success: false, 
            error: '目标项目服务不可用' 
          };
          continue;
        }
        
        // 调用目标项目的项目事件处理函数
        if (targetService.onProjectEvent) {
          const result = await targetService.onProjectEvent(event);
          results[targetProject] = result;
        } else {
          results[targetProject] = { 
            success: false, 
            error: '目标项目未实现项目事件处理' 
          };
        }
      }
      
      // 如果所有目标项目都处理失败，则返回失败
      const allFailed = Object.values(results).every(r => !r.success);
      if (allFailed) {
        return { 
          success: false, 
          error: '所有目标项目处理失败', 
          data: { results } 
        };
      }
      
      return { success: true, data: { results } };
    } catch (err) {
      console.error('[EventService] 处理项目事件异常:', err);
      return { success: false, error: err.message || '处理异常' };
    }
  }
  
  /**
   * 处理任务相关事件
   * @param {Object} event 事件对象
   * @returns {Promise<Object>} 处理结果
   */
  async _processTaskEvent(event) {
    console.log(`[EventService] 处理任务事件: ${event.type}`);
    
    // 任务事件处理逻辑，与项目事件类似
    try {
      const results = {};
      
      for (const targetProject of event.targetProjects) {
        const targetService = global.CROSS_SERVICE 
          && global.CROSS_SERVICE[targetProject.toUpperCase()];
        
        if (!targetService) {
          results[targetProject] = { 
            success: false, 
            error: '目标项目服务不可用' 
          };
          continue;
        }
        
        if (targetService.onTaskEvent) {
          const result = await targetService.onTaskEvent(event);
          results[targetProject] = result;
        } else {
          results[targetProject] = { 
            success: false, 
            error: '目标项目未实现任务事件处理' 
          };
        }
      }
      
      const allFailed = Object.values(results).every(r => !r.success);
      if (allFailed) {
        return { 
          success: false, 
          error: '所有目标项目处理失败', 
          data: { results } 
        };
      }
      
      return { success: true, data: { results } };
    } catch (err) {
      console.error('[EventService] 处理任务事件异常:', err);
      return { success: false, error: err.message || '处理异常' };
    }
  }
  
  /**
   * 处理流程相关事件
   * @param {Object} event 事件对象
   * @returns {Promise<Object>} 处理结果
   */
  async _processFlowEvent(event) {
    console.log(`[EventService] 处理流程事件: ${event.type}`);
    
    // 流程事件处理逻辑类似项目事件
    try {
      const results = {};
      
      for (const targetProject of event.targetProjects) {
        const targetService = global.CROSS_SERVICE 
          && global.CROSS_SERVICE[targetProject.toUpperCase()];
        
        if (!targetService) {
          results[targetProject] = { 
            success: false, 
            error: '目标项目服务不可用' 
          };
          continue;
        }
        
        if (targetService.onFlowEvent) {
          const result = await targetService.onFlowEvent(event);
          results[targetProject] = result;
        } else {
          results[targetProject] = { 
            success: false, 
            error: '目标项目未实现流程事件处理' 
          };
        }
      }
      
      const allFailed = Object.values(results).every(r => !r.success);
      if (allFailed) {
        return { 
          success: false, 
          error: '所有目标项目处理失败', 
          data: { results } 
        };
      }
      
      return { success: true, data: { results } };
    } catch (err) {
      console.error('[EventService] 处理流程事件异常:', err);
      return { success: false, error: err.message || '处理异常' };
    }
  }
  
  /**
   * 处理文档相关事件
   * @param {Object} event 事件对象
   * @returns {Promise<Object>} 处理结果
   */
  async _processDocEvent(event) {
    console.log(`[EventService] 处理文档事件: ${event.type}`);
    
    // 文档事件处理逻辑类似项目事件
    try {
      const results = {};
      
      for (const targetProject of event.targetProjects) {
        const targetService = global.CROSS_SERVICE 
          && global.CROSS_SERVICE[targetProject.toUpperCase()];
        
        if (!targetService) {
          results[targetProject] = { 
            success: false, 
            error: '目标项目服务不可用' 
          };
          continue;
        }
        
        if (targetService.onDocEvent) {
          const result = await targetService.onDocEvent(event);
          results[targetProject] = result;
        } else {
          results[targetProject] = { 
            success: false, 
            error: '目标项目未实现文档事件处理' 
          };
        }
      }
      
      const allFailed = Object.values(results).every(r => !r.success);
      if (allFailed) {
        return { 
          success: false, 
          error: '所有目标项目处理失败', 
          data: { results } 
        };
      }
      
      return { success: true, data: { results } };
    } catch (err) {
      console.error('[EventService] 处理文档事件异常:', err);
      return { success: false, error: err.message || '处理异常' };
    }
  }
  
  /**
   * 获取事件类型常量
   * @returns {Object} 事件类型常量
   */
  getEventTypes() {
    return EVENT_TYPE;
  }
  
  /**
   * 获取项目标识常量
   * @returns {Object} 项目标识常量
   */
  getProjectIds() {
    return PROJECT_ID;
  }
}

module.exports = new EventService(); 